package com.gsi.webstore.platform.storefront.pipelet.orderprocess;

import com.gsi.webstore.platform.adapter.storelocator.capi.StoreLocatorManager;
import com.gsi.webstore.platform.adapter.storelocator.internal.client.data.Storefront;
import com.intershop.beehive.core.capi.naming.NamingMgr;
import com.intershop.beehive.core.capi.pipeline.Pipelet;
import com.intershop.beehive.core.capi.pipeline.PipelineDictionary;
import com.intershop.beehive.core.capi.pipeline.PipelineInitializationException;
import com.intershop.beehive.core.capi.request.Request;
import com.intershop.beehive.core.capi.pipeline.PipeletExecutionException;
import com.intershop.beehive.bts.capi.orderprocess.LineItem;
import com.intershop.beehive.bts.capi.orderprocess.basket.Basket;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 
 */
public class GetStoreFrontMapFromCart extends Pipelet
{
    /**
     * Constant used to access the pipeline dictionary with key 'Cart'
     * 
     * The current cart
     */
    public static final String DN_CART = "Cart";
    
    /**
     * Constant used to access the pipeline dictionary with key 'CartStoreFrontMap'
     * 
     * Map of store front id's to store front objects
     */
    public static final String DN_STORE_FRONT_MAP = "StoreFrontMap";
    
    /**
     * Constant used to access the pipeline dictionary with key 'CurrentRequest'
     * 
     * The current request
     */
    public static final String DN_CURRENT_REQUEST = "CurrentRequest";
    
    private StoreLocatorManager storeLocatorMgr = null;
    private String storeFrontIdAttribute = "STORE_ID";
    
    public void init() throws PipelineInitializationException
    {
        storeLocatorMgr = (StoreLocatorManager)NamingMgr.getManager(StoreLocatorManager.class);
    }

    /**
     * The pipelet's execute method is called whenever the pipelets gets
     * executed in the context of a pipeline and a request. The pipeline
     * dictionary valid for the currently executing thread is provided as a
     * parameter.
     * 
     * @param dict
     *            The pipeline dictionary to be used.
     * @throws PipeletExecutionException
     *             Thrown in case of severe errors that make the pipelet execute
     *             impossible (e.g. missing required input data).
     */
    public int execute(PipelineDictionary dict)
        throws PipeletExecutionException 
    {        
        // lookup 'CurrentRequest' in pipeline dictionary
        Request currentRequest = (Request)dict.get(DN_CURRENT_REQUEST);
        if (null == currentRequest)
        {
            throw new PipeletExecutionException(
                            "Mandatory input parameter 'CurrentRequest' not available in pipeline dictionary.");
        }
        
        // lookup 'Cart' in pipeline dictionary
        Basket cart = (Basket)dict.get(DN_CART);
        if (null == cart)
        {
            throw new PipeletExecutionException("Mandatory input parameter 'Cart' not available in pipeline dictionary.");
        }

        String localeId = null;
        Long storeId = null;
        Map<Long, Storefront> storeFrontMap = new HashMap<Long, Storefront>();
        
        localeId = currentRequest.getLocale().getLocaleID();
        Iterator<LineItem> lineItemsIterator = cart.createLineItemsIterator();
        
        while (lineItemsIterator != null && lineItemsIterator.hasNext()) 
        {
            LineItem currentLineItem = lineItemsIterator.next();
            storeId = (Long)currentLineItem.getAttribute(storeFrontIdAttribute);
            if (storeFrontMap.get(storeId) == null) 
            {
                if (storeId != null) 
                {
                    Storefront storeFront = storeLocatorMgr.getStorefront(storeId, localeId);
                    storeFrontMap.put(storeId, storeFront);
                }
            }
        }
        
        dict.put(DN_STORE_FRONT_MAP, storeFrontMap);
        
        return PIPELET_NEXT;
    }
}